package za.org.jcicada.datastore.impl;

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import za.org.jcicada.genss.ServiceURN;
import za.org.jcicada.genss.messages.Result;
import za.org.jcicada.genss.messages.SuccessCode;
import za.org.jcicada.genss.sensor.ISensor;
import za.org.jcicada.genss.sensor.ISensorObserver;
import za.org.jcicada.genss.sensor.ISensorSubject;
import za.org.jcicada.genss.sensor.ISensorValue;
import za.org.jcicada.genss.sensor.SensorURN;
import za.org.jcicada.genss.sensor.impl.SensorStatusValue;
import za.org.jcicada.genss.sensor.impl.StrategyAuto;

public class SensorObserver implements ISensorObserver {

    /** Class logger */
    private static final Log logger = LogFactory.getLog(SensorObserver.class);
    
    private ISensorSubject sensorSubject;
    private DataStoreServerAbstract dataStoreServer;
    private Set<SensorURN> sensorURNs;
    private int counter;
    private int statusCounter;
    
    public SensorObserver(ISensorSubject sensorSubject, DataStoreServerAbstract dataStoreServer) {
    	this.sensorSubject = sensorSubject;
    	this.dataStoreServer = dataStoreServer;
    }
    
    public void initialize() {
    	sensorURNs = new HashSet<SensorURN>();
    	sensorSubject.requestSensorSet(this);
    	counter = 0;
    	statusCounter = 0;
    }
    
    public void shutdown() {
    	sensorSubject.informDisconnect(this);
    	sensorURNs.clear();
    }
    
    public int getCounter() {
    	return counter;
    }
    
    public int getStatusCounter() {
    	return statusCounter;
    }
    
	public void informDisconnect() {
		// do nothing
	}

	synchronized final public void informSensor(SensorURN sensorURN, ISensorValue value) {
		logger.debug(String.format("%s, %s", sensorURN, value));
		dataStoreServer.storeSensor(sensorURN, value);
		counter++;
	}
	
	synchronized final public void informSensorStatus(SensorURN sensorURN, SensorStatusValue statusValue) {
		logger.debug(String.format("%s, %s", sensorURN, statusValue));
		dataStoreServer.storeSensorStatus(sensorURN, statusValue);
		statusCounter++;
	}
	
	public void informSensorType(SensorURN sensorURN, ISensor sensor) {
		logger.debug(String.format("%s, %s", sensorURN, sensor.getName()));
		sensorURNs.add(sensorURN);
	}

	public void informTerminateService(ServiceURN serviceURN) {
		logger.warn(serviceURN.toString());
	}

	public void replyAttach(Result result, Set<SensorURN> sensorURNs) {
		logger.debug(String.format("%s, %s", result, sensorURNs));
		if (result.getCode().equals(SuccessCode.COMPLETE_SUCCESS)) {
			for (SensorURN sensorURN : sensorURNs) {
				sensorSubject.requestSetSamplingStrategy(this, new StrategyAuto(sensorURN));
			}
		}
	}

	public void replyDetach(Result result, Set<SensorURN> sensorURNs) {
	}

	public void replySensorSet(Result result, int numSensors) {
		logger.info(String.format("%s, %d", result, numSensors));
		sensorSubject.requestAttach(this, sensorURNs);
	}

	public void replySetSamplingStrategy(Result result) {
	}

}
